package com.asiainfo.framework.listener;

import cn.hutool.core.net.NetUtil;
import com.asiainfo.common.utils.StringUtils;
import com.asiainfo.framework.config.ProjectConfig;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.lang.management.ManagementFactory;
import java.net.Inet4Address;
import java.util.stream.Collectors;

/**
 * 程序启动监听器
 *
 * @author novel
 * @date 2019/12/11
 */
@Component
@Slf4j
public class AppStartListener {
    private final RedisTemplate<Object, Object> redisTemplate;
    private final ProjectConfig projectConfig;

    public AppStartListener(RedisTemplate<Object, Object> redisTemplate, ProjectConfig projectConfig) {
        this.redisTemplate = redisTemplate;
        this.projectConfig = projectConfig;
    }


    @EventListener
    @Async
    public void onApplicationEvent(ApplicationReadyEvent event) {
//        FastJson2JsonRedisSerializer<Object> serializer = new FastJson2JsonRedisSerializer<>(Object.class);
//        redisTemplate.setValueSerializer(serializer);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.afterPropertiesSet();

        printProjectInfo(event);
    }

    private void printProjectInfo(ApplicationReadyEvent event) {
        Class<?> mainClass = event.getSpringApplication().getMainApplicationClass();
        Logger logger = LoggerFactory.getLogger(mainClass);
        Environment env = event.getApplicationContext().getEnvironment();
        logger.info("=========================================================================================================");
        String profile = env.getProperty("spring.profiles.active");
        String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
        Runtime runtime = Runtime.getRuntime();
        float maxMemory = runtime.maxMemory() / (1024 * 1024);
        float usedMemory = (runtime.totalMemory() - runtime.freeMemory()) / 1024 / 1024;
        String urls = getAccessUrls(env);
        logger.info("Project use [ {} ] active profile, process pid is {}", profile, pid);
        logger.info(String.format("JVM memory (used/max): %.2fMB / %.2fMB", usedMemory, maxMemory));
        logger.info("Run at {}", urls);
        logger.info("=========================================================================================================");
    }

    private String getAccessUrls(Environment env) {
        return NetUtil.localAddressList(s -> s instanceof Inet4Address).stream()
                .map(addr -> {
                    String port = env.getProperty("server.port");
                    String contextPath = env.getProperty("server.servlet.contextPath");
                    if (StringUtils.isEmpty(contextPath)) {
                        contextPath = "";
                    }
                    return String.format("http://%s:%s%s", addr.getHostAddress(), port, contextPath);
                })
                .collect(Collectors.joining(" "));
    }

}
